<script lang="ts">
import { Component, Vue, Prop } from 'vue-property-decorator'
import { CreateElement } from 'vue'
import { Upload } from 'element-ui'
import { globalErrorHandler } from '@/utils'

@Component({
  name: 'FileUpload'
})
export default class extends Vue {
  // size limit when uploading, byte
  @Prop({ type: Number, required: false, default: 0 })
  private sizeLimit!: number
  // button text
  @Prop({ type: String, required: false, default: 'upload' })
  private placeholder!: string
  // tip
  @Prop({ type: String, required: false, default: '' })
  private tip!: string

  private loading = false

  get uploadAttrs () {
    return {
      'on-success': this.onSuccess,
      'on-error': this.onError,
      'before-upload': this.beforeUpload,
      'on-exceed': this.onExceed,
      ...this.$attrs,
      disabled: this.$attrs.disabled || this.loading
    }
  }

  private onSuccess (r: any): void {
    this.loading = false
    this.$emit('success', r)
  }
  private onError (e: Error): void {
    this.loading = false
    this.$message.error('upload failed')
    globalErrorHandler(e)
  }
  private beforeUpload (file: File): boolean {
    this.loading = true

    if (this.sizeLimit === 0) {
      return true
    } else {
      let size = file.size <= this.sizeLimit

      if (!size) {
        this.$message.warning('the selected file is too large')
        this.loading = false
      }

      return size
    }
  }
  private onExceed (): void {
    this.$msgbox({
      title: 'warning',
      message: 'please clear and continue',
      type: 'warning',
      showClose: false,
      showCancelButton: true,
      confirmButtonText: 'clear'
    })
      .then(() => {
        ;(this.$refs['file-upload'] as Upload).clearFiles()
      })
      .catch(() => {})
  }

  render (h: CreateElement) {
    let trigger = h(
      'el-button',
      {
        props: {
          type: 'primary',
          loading: this.loading,
          icon: 'el-icon-upload'
        },
        slot: 'trigger'
      },
      this.placeholder
    )

    let tip = h(
      'div',
      { class: { 'file-upload-tip': true, hide: !this.tip } },
      this.tip
    )

    return h(
      'el-upload',
      { props: this.uploadAttrs, on: this.$listeners, ref: 'file-upload' },
      [trigger, tip]
    )
  }
}
</script>

<style lang="scss" scoped>
.file-upload-tip {
  font-size: 12px;
  color: $info;
  &.hide {
    display: none;
  }
}
</style>
